package pri.zxx.webdemo.config.timemonitor;

import org.apache.commons.collections4.CollectionUtils;

import java.util.LinkedList;
import java.util.List;

/**
 * <p>description</p>
 *
 * @author <a href="mailto:zxxcof@qq.com">zxx</a>
 * @since 2020/10/12 11:42
 */
public class MethodTrack {
    private String methodName;
    private long cost;
    private long start;
    private long end;
    private int depth = 0;
    private int count = 0;
    private long total;
    private long max;
    private long min;
    private long avg;


    private MethodTrack parent;
    private List<MethodTrack> children = new LinkedList<>();

    public MethodTrack(String methodName, long start, MethodTrack parent) {
        this.methodName = methodName;
        this.start = start;
        this.parent = parent;
        this.depth = parent.getDepth() + 1;
    }

    public MethodTrack() {
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public long getStart() {
        return start;
    }

    public void setStart(long start) {
        this.start = start;
    }

    public long getEnd() {
        return end;
    }

    public void setEnd(long end) {
        this.end = end;
    }


    public List<MethodTrack> getChildren() {
        return children;
    }

    public void setChildren(List<MethodTrack> children) {
        this.children = children;
    }


    public long getCost() {
        return cost;
    }

    public void setCost() {
        this.cost = this.end - this.start;
    }

    public void setCost(long cost) {
        this.cost = cost;
    }

    public MethodTrack getParent() {
        return parent;
    }

    public void setParent(MethodTrack parent) {
        this.parent = parent;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(methodName).append("()")
                .append(",total cost: ").append(total).append("ms");
        if (count > 1) {
            builder.append(",execute count: ").append(count).append(",")
                    .append("average time: ").append(avg).append("ms,")
                    .append("max time: ").append(max).append("ms");
        }
        if (CollectionUtils.isNotEmpty(children)) {
            children.forEach(e -> {
                builder.append("\n");
                for (int i = 0; i < e.depth; i++) {
                    builder.append("  ");
                }
                builder.append('-').append(e.toString());
            });
        }
        return builder.toString();
    }

    public MethodTrack findChild(String methodName) {
        return this.children.stream()
                .filter(e -> e.getMethodName().equals(methodName))
                .findAny()
                .orElse(null);
    }

    public int getDepth() {
        return depth;
    }

    public void setDepth(int depth) {
        this.depth = depth;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public long getMax() {
        return max;
    }

    public void setMax(long max) {
        this.max = max;
    }

    public long getMin() {
        return min;
    }

    public void setMin(long min) {
        this.min = min;
    }

    public long getAvg() {
        return avg;
    }

    public void setAvg(long avg) {
        this.avg = avg;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }
}